STATUS_WAIT = 0
STATUS_UNKNOWN_ERROR = -2  # 发生了错误
STATUS_TWO_ORDER_FILLED_ERROR = -1  # 补仓单和平仓单同时被触发
STATUS_NO_POSITION = 1  # 空仓
STATUS_PENDING_OPENING_ORDER = 2  # 提交了开仓订单，等待结果
STATUS_HOLDING = 3  # 持仓中，没有订单
STATUS_PENDING_CLOSE_ORDER = 5  # 提交了平仓订单，等待结果
STATUS_REACH_MAX_MARGIN = 6  # 达到了最大保证金
STATUS_REACH_MAX_STAGE = 7  # 达到了最大补仓次数
STATUS_PENDING_CANCEL_BUY = 8  # 提交了取消加仓的订单
STATUS_PENDING_CANCEL_CLOSE = 9  # 提交了取消平仓
STATUS_WAIT_ADD_CD = 10  # 等待加仓CD
LONG = "LONG"
SHORT = "SHORT"

EXIT_MODE_STOP_LOSE = 1
EXIT_MODE_PERIOD_LOW = 2


class Turtle:
    def __init__(self):
        # 交易货币
        self.trade_symbol = ""
        # k线级别
        self.period = ""
        # 倍率
        self.leverage = None
        # 每次开仓金额
        self.position_amount = 0
        self.atr_period = 14
        self.entry_period = 14
        self.exit_period = 14
        self.price_precision = 0
        self.quantity_precision = 0
        self.tick_price_precision = 0
        # 最小开仓数量
        self.min_qty = 0

        # 现价
        self.current_price = 0
        # 上一根k线的时间
        self.last_kline_ts = 0
        self.status = STATUS_NO_POSITION
        # 量
        self.quantity = 0
        # 多还是空
        self.position_side = None
        # 开仓订单号
        self.open_order_id = None
        # 退出订单号
        self.long_exit_1_order_id = None
        # 止损价位
        self.stop_lose_price = 0
        # 止损订单号
        self.stop_lose_order_id = None
        # 波动
        self.n = 0
        self.long_entry_1 = 0
        self.last_long_exit_1 = 0
        self.long_exit_1 = 0
        self.next_buy_price = 0
        self.stage = 0
        self.qty_n = 0
        self.max_stage = 0
        self.next_buy_prices = []
        self.open_price = 0
        self.exit_mode = EXIT_MODE_STOP_LOSE

    def change_status(self, status):
        self.status = status

    def gen_next_buy_prices(self):
        for i in range(0, self.max_stage):
            self.next_buy_prices.append(round(self.current_price + 0.5 * self.n * i, self.price_precision))

        self.next_buy_prices.append(99999999)

    def get_next_buy_price(self):
        return self.next_buy_prices[self.stage]

    def reset(self):
        self.n = 0
        self.long_entry_1 = 0
        self.last_long_exit_1 = 0
        self.long_exit_1 = 0
        self.next_buy_price = 0
        self.stage = 0
        self.qty_n = 0
        self.next_buy_prices = []
        self.quantity = 0
        self.status = STATUS_NO_POSITION
        self.open_order_id = None
        self.stop_lose_order_id = None
        self.long_exit_1_order_id = None
        self.last_kline_ts = 0

    def to_json(self):
        json_obj = {"trade_symbol": self.trade_symbol, "period": self.period,
                    "leverage": self.leverage, "position_amount": self.position_amount,
                    "atr_period": self.atr_period, "entry_period": self.entry_period,
                    "exit_period": self.exit_period, "price_precision": self.price_precision,
                    "quantity_precision": self.quantity_precision, "tick_price_precision": self.tick_price_precision,
                    "min_qty": self.min_qty, "current_price": self.current_price,
                    "last_kline_ts": self.last_kline_ts, "status": self.status,
                    "quantity": self.quantity, "position_side": self.position_side,
                    "open_order_id": self.open_order_id, "long_exit_1_order_id": self.long_exit_1_order_id,
                    "stop_lose_price": self.stop_lose_price, "stop_lose_order_id": self.stop_lose_order_id,
                    "n": self.n, "long_entry_1": self.long_entry_1,
                    "last_long_exit_1": self.last_long_exit_1, "long_exit_1": self.long_exit_1,
                    "next_buy_price": self.next_buy_price, "stage": self.stage, "qty_n": self.qty_n,
                    "max_stage": self.max_stage, "next_buy_prices": self.next_buy_prices,
                    "open_price": self.open_price, "exit_mode": self.exit_mode
                    }
        return json_obj

    @staticmethod
    def parse_from_json(o):
        t = Turtle()
        t.trade_symbol = o['trade_symbol']
        t.period = o['period']
        t.leverage = o['leverage']
        t.position_amount = o['position_amount']
        t.atr_period = o['atr_period']
        t.entry_period = o['entry_period']
        t.exit_period = o['exit_period']
        t.price_precision = o['price_precision']
        t.quantity_precision = o['quantity_precision']
        t.tick_price_precision = o['tick_price_precision']
        t.min_qty = o['min_qty']
        t.current_price = o['current_price']
        # t.last_kline_ts = o['last_kline_ts']
        t.status = o['status']
        t.quantity = o['quantity']
        t.position_side = o['position_side']
        t.open_order_id = o['open_order_id']
        t.long_exit_1_order_id = o['long_exit_1_order_id']
        t.stop_lose_price = o['stop_lose_price']
        t.stop_lose_order_id = o['stop_lose_order_id']
        t.n = o['n']
        t.long_entry_1 = o['long_entry_1']
        t.last_long_exit_1 = o['last_long_exit_1']
        t.long_exit_1 = o['long_exit_1']
        t.next_buy_price = o['next_buy_price']
        t.stage = o['stage']
        t.qty_n = o['qty_n']
        t.max_stage = o['max_stage']
        t.next_buy_prices = o['next_buy_prices']
        t.open_price = o['open_price']
        t.exit_mode = o['exit_mode']
        return t

